package net.simflow.swf.analyzer.gui.chart;

import net.simflow.swf.analyzer.data.ColorPkg;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.swtchart.Chart;
import org.swtchart.IAxis;
import org.swtchart.ILineSeries;
import org.swtchart.ISeries;
import org.swtchart.IAxis.Direction;
import org.swtchart.ISeries.SeriesType;

public class ChartCreator {
	private static ChartCreator instance = new ChartCreator();

	private ChartCreator() {
	}

	public static ChartCreator getInstance() {
		return instance;
	}

	public void createLineChart(Composite parent, String chartTitle,
			String xAxisTitle, String yAxisTitle, double[] x, double[] y,
			final String[] tip, String dataTitle) {
		final Chart chart = createChart(parent, chartTitle, xAxisTitle,
				yAxisTitle);

		ILineSeries lineSeries = (ILineSeries) chart.getSeriesSet()
				.createSeries(SeriesType.LINE, dataTitle);
		lineSeries.setXSeries(x);
		lineSeries.setYSeries(y);

		lineSeries.setLineColor(ColorPkg.getColor(ColorPkg.ORANGE));
		lineSeries.setLineWidth(1);
		lineSeries.setSymbolColor(ColorPkg.getColor(ColorPkg.ORANGE));

		lineSeries.getSymbolSize();

		chart.getPlotArea().addMouseMoveListener(new MouseMoveListener() {
			public void mouseMove(MouseEvent e) {
				for (ISeries series : chart.getSeriesSet().getSeries()) {
					for (int i = 0; i < series.getYSeries().length; i++) {
						Point p = series.getPixelCoordinates(i);
						double distance = Math.sqrt(Math.pow(e.x - p.x, 2)
								+ Math.pow(e.y - p.y, 2));

						if (distance < ((ILineSeries) series).getSymbolSize()) {
							setToolTipText(series, i);
							return;
						}
					}
				}
				chart.getPlotArea().setToolTipText(null);
			}

			private void setToolTipText(ISeries series, int index) {
				chart.getPlotArea().setToolTipText(tip[index]);
			}
		});

		chart.getAxisSet().adjustRange();
	}

	private Chart createChart(Composite parent, String chartTitle,
			String xAxisTitle, String yAxisTitle) {

		final Chart chart = new Chart(parent, SWT.NONE);

		chart.getTitle().setText(chartTitle);
		chart.getAxisSet().getXAxis(0).getTitle().setText(xAxisTitle);
		chart.getAxisSet().getYAxis(0).getTitle().setText(yAxisTitle);
		chart.setBackground(ColorPkg.getColor(ColorPkg.WHITE));

		chart.getLegend().setVisible(false);
		chart.getTitle().setForeground(ColorPkg.getColor(ColorPkg.BLACK));
		chart.getAxisSet().getXAxis(0).getTitle()
				.setForeground(ColorPkg.getColor(ColorPkg.BLACK));
		chart.getAxisSet().getXAxis(0).getTick()
				.setForeground(ColorPkg.getColor(ColorPkg.BLACK));
		chart.getAxisSet().getYAxis(0).getTitle()
				.setForeground(ColorPkg.getColor(ColorPkg.BLACK));
		chart.getAxisSet().getYAxis(0).getTick()
				.setForeground(ColorPkg.getColor(ColorPkg.BLACK));

		chart.addMouseMoveListener(new MouseMoveListener() {
			public void mouseMove(MouseEvent e) {
				for (IAxis axis : chart.getAxisSet().getAxes()) {
					Rectangle r = axis.getTick().getBounds();

					// check if mouse cursor is on axis tick
					if (r.x < e.x && e.x < r.x + r.width && r.y < e.y
							&& e.y < r.y + r.height) {

						// get pixel coordinate on axis tick
						int pixelCoord;
						if (axis.getDirection() == Direction.X) {
							pixelCoord = e.x - r.x;
						} else {
							pixelCoord = e.y - r.y;
						}

						// get data coordinate
						double dataCoord = axis.getDataCoordinate(pixelCoord);

						// show tool-tip
						chart.setToolTipText(String.valueOf(dataCoord));
						return;
					}
				}
				chart.setToolTipText(null);
			}
		});

		return chart;
	}
}
